#include<iostream>
#include<cmath>
#include<string>
#include<stack>
using namespace std;

/** 
 * 根据输入的数和操作符给出对应的结果
 * 
 * @param n1 操作符前的数
 * @param n2 操作符后的数
 * @param c 操作符
 * 
 * @return 结果
 */
double result(double n1,double n2,char c)
{
    switch(c)
    {
    case '+':
	return n1+n2;
    case '-':
	return n1-n2;
    case '*':
	return n1*n2;
    case '/':
	return n1/n2;
    case '^':
	return pow(n1,n2);
    default:
	cerr<<"错误的符号"<<endl;
	return -1;
    }
}

/** 
 * 给出操作符的优先级
 * 数字越大优先级越大
 * @param opt 操作符
 * 
 * @return 返回优先级大小
 */
int priority(char opt)
{
    switch(opt)
    {
    case '(':
	return 1;
    case '+':
    case '-':
	return 2;
    case '*':
    case '/':
	return 3;
    case '^':
	return 4;
    default:
	cerr<<"错误的符号"<<endl;
	return -1;
    }
}

int caculate(string str)
{
    stack<char> opts;/// 操作符栈
    stack<double> data;/// 数据栈
    /// temp1和temp2用于临时存放数据栈中弹出的数，value用于存放输入字符串中的数值
    double temp1,temp2,value=0;
    int flag=0;/// 用于标记当前数字在小数点后第几位，0表示小数点为出现
    for(string::iterator itr=str.begin();itr!=str.end();++itr)
    {
	if(*itr=='+'||*itr=='-'||*itr=='*'||*itr=='/'||*itr=='^')
	{
	    /// 操作符栈中优先级高的运算符先计算并同步更新数据栈
	    while(!opts.empty()&&priority(opts.top())>=priority(*itr))
	    {
		/// 若数据栈提前空了，则有多余的表达式报错并退出中止函数
		if(data.empty())
		{
		    cerr<<"多余的符号"<<endl;
		    return -1;
		}
		temp2=data.top();
		data.pop();
		if(data.empty())
		{
		    cerr<<"多余的符号"<<endl;
		    return -1;
		}
		temp1=data.top();
		data.pop();
		/// 若除数为0则报错
		if(opts.top()=='/'&&temp2==0)
		{
		    cerr<<"除数不能为0"<<endl;
		    return -1;
		}
		data.push(result(temp1,temp2,opts.top()));
		opts.pop();
	    }
	    opts.push(*itr);
	    continue;
	}
	///左括号直接压入栈中 
	if(*itr=='(')
	{
	    opts.push(*itr);
	    continue;
	}
	/// 遇到右括号，将操作符从栈中弹出直到左括号
	if(*itr==')')
        {
	    while(!opts.empty()&&opts.top()!='(')
	    {
		if(data.empty())
		{
		    cerr<<"多余的符号"<<endl;
		    return -1;
		}
		temp2=data.top();
		data.pop();
		if(data.empty())
		{
		    cerr<<"多余的符号"<<endl;
		    return -1;
		}
		temp1=data.top();
		data.pop();
		data.push(result(temp1,temp2,opts.top()));
		opts.pop();
	    }
	    /// 若操作符栈为空，则说明右括号没有遇到对应的左括号报错并中止函数
	    if(opts.empty())
	    {
		cerr<<"缺少左括号"<<endl;
		return -1;
	    }
	    opts.pop();
	    continue;
        }
	/// 处理字符串中的数字
	if((*itr<='9'&&*itr>='0')||*itr=='.')
	{
	    if(flag==0)
	    {
		if(*itr=='.')
		{
		    flag=1;
		    continue;
		}
		else
		{
		    value=value*10+(double)(*itr-'0');
		}
	    }
	    else
	    {
		if(*itr=='.')
		{
		    cerr<<"多余的小数点"<<endl;
		    return -1;
		}
		else
		{
		    value=value+(double)(*itr-'0')*pow(10,-flag);
		    flag++;
		}
	    }
	    if(!((*(itr+1)<='9'&&*(itr+1)>='0')||*(itr+1)=='.'))
	    {
		data.push(value);
		value=0;
		flag=0;
	    }
	    continue;
	}
	/// 若字符串中有其他字符报错
	cerr<<"错误的符号"<<endl;
	return -1;
    }
    /// 遍历完字符串后若操作符栈非空则全部弹出
    while(!opts.empty())
    {
	/// 若操作符栈中还有左括号，则说明遍历中没有遇到对应的右括号报错并中止函数
	if(opts.top()=='(')
	{
	    cerr<<"缺少右括号"<<endl;
	    return -1;
	}
	if(data.empty())
	{
	    cerr<<"多余的符号"<<endl;
	    return -1;
	}
        temp2=data.top();
	data.pop();
	if(data.empty())
	{
	    cerr<<"多余的符号"<<endl;
	    return -1;
	}
	temp1=data.top();
	data.pop();
	data.push(result(temp1,temp2,opts.top()));
	opts.pop();
    }
    /// 若最后输出数据栈元素多于一个说明表达式中缺少操作符，报错并中止函数
    if(data.size()!=1)
    {
	cerr<<"缺少符号"<<endl;
	return -1;
    }
     /// 最后的结果在数据栈中输出
    cout<<data.top()<<endl;
    return 0;
}
